package com.bub.pay.core.manager.role;

import com.alibaba.fastjson.JSON;
import com.bub.pay.core.base.BaseManagerAbstract;
import com.bub.pay.core.base.IBaseManager;
import com.bub.pay.core.dao.SysRoleDao;
import com.bub.pay.core.dao.SysRolePermDao;
import com.bub.pay.core.dao.SysUserRoleDao;
import com.bub.pay.core.entity.domain.SysRole;
import com.bub.pay.core.entity.domain.SysRolePerm;
import com.bub.pay.core.entity.domain.SysUserRole;
import com.bub.pay.core.entity.dto.user.UserSimpleDTO;
import com.bub.pay.core.entity.vo.user.AddRoleVo;
import com.bub.pay.core.entity.vo.user.UpdateRoleVo;
import com.bub.pay.core.enums.DeleteFlagEnum;
import com.bub.pay.core.manager.system.CurrentSystemManager;
import com.bub.pay.framework.common.base.Cause;
import com.bub.pay.framework.common.exception.GlobalException;
import com.bub.pay.framework.redis.RedisClient;
import com.bub.pay.framework.redis.RedisKeyPrefix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;

/**
 * 角色服务
 */
@Service
public class RoleManager extends BaseManagerAbstract<SysRole, SysRoleDao> implements IBaseManager<SysRole> {
    private final Logger logger = LoggerFactory.getLogger(RoleManager.class);

    @Resource
    private SysRoleDao sysRoleDao;

    @Resource
    private SysRolePermDao sysRolePermDao;

    @Resource
    private RedisClient redisClient;

    @Resource
    private SysUserRoleDao userRoleDao;

    @Resource
    private SysRoleDao roleDao;

    @Resource
    private CurrentSystemManager currentSystemManager;

    @Transactional
    public int addRole(AddRoleVo addRoleVo) {
        SysRole role = new SysRole();
        BeanUtils.copyProperties(addRoleVo, role);
        if (sysRoleDao.insertSelective(role) == 0) {
            logger.error("总管理|添加角色失败||参数{}", JSON.toJSONString(addRoleVo));
            throw new GlobalException(currentSystemManager.getModule(), Cause.admin_add_role_fail);
        }
        return 1;
    }

    @Transactional
    public int updateRole(UpdateRoleVo updateRoleVo) {
        SysRole role = new SysRole();
        BeanUtils.copyProperties(updateRoleVo, role);
        role.setId(updateRoleVo.getRoleId());
        role.setExtendId(updateRoleVo.getExtendId());
        if(sysRoleDao.updateByPrimaryKeySelective(role) == 0){
            throw new GlobalException(currentSystemManager.getModule(),Cause.operat_fail);
        }
        deleteRolePremCache(updateRoleVo.getRoleId());
        return 1;
    }

    @Transactional
    public int deleteRole(UpdateRoleVo deleteRoleVo) {
    	// 校验
		Example example = new Example(SysRole.class);
		example.createCriteria()
				.andEqualTo("id",deleteRoleVo.getRoleId())
				.andEqualTo("extendId",deleteRoleVo.getExtendId())
				.andEqualTo("delFlag", DeleteFlagEnum.using.flag);
		SysRole bnSysRole = sysRoleDao.selectOneByExample(example);
		if (bnSysRole == null) {
			throw new GlobalException(currentSystemManager.getModule(), Cause.admin_delte_role_not_presence_error);
		}
		if (bnSysRole.getIsSys().equals(1)) {
			throw new GlobalException(currentSystemManager.getModule(), Cause.can_not_delete_sys_role);
		}


        //删除角色
        SysRole role = new SysRole();
        role.setDelFlag(true);
        Example exampleSysRole = new Example(SysRole.class);
        exampleSysRole.createCriteria().andEqualTo("id",deleteRoleVo.getRoleId())
            .andEqualTo("extendId",deleteRoleVo.getExtendId());
        int i = sysRoleDao.updateByExampleSelective(role,exampleSysRole);
        if (i == 0) {
            logger.error("总管理|删除角色失败||参数{}", JSON.toJSONString(role));
            throw new GlobalException(currentSystemManager.getModule(), Cause.admin_delte_role_fail);
        }
        //删除角色-用户关联关系
        SysUserRole userRole = new SysUserRole();
        userRole.setDelFlag(true);
        Example exampleUserRole= new Example(SysUserRole.class);
        exampleUserRole.createCriteria().andEqualTo("roleId",deleteRoleVo.getRoleId());
        userRoleDao.updateByExampleSelective(userRole,exampleUserRole);
        //删除角色-权限关联关系
        SysRolePerm sysRolePerm = new SysRolePerm();
        sysRolePerm.setDelFlag(true);
        Example permExample = new Example(SysRolePerm.class);
        permExample.createCriteria().andEqualTo("roleId", deleteRoleVo.getRoleId());
        sysRolePermDao.updateByExampleSelective(sysRolePerm,permExample);
        return i;
    }

    @Transactional(readOnly = true)
    public List<UserSimpleDTO> queryUserByRole(UpdateRoleVo queryVo) {
        return userRoleDao.queryUserByRole(queryVo.getRoleId());
    }

    @SuppressWarnings("unchecked")
    public List<SysRole> queryRolesByUserId(Long userId, int userType, boolean refreshFlag) {
        final String key = "ROLES:" + userId.toString();
        if (redisClient.exists(RedisKeyPrefix.CACHE, key) && !refreshFlag) {
            return (List<SysRole>) redisClient.get(RedisKeyPrefix.CACHE, key);
        } else {
            List<SysRole> roleList = roleDao.queryRoleByUserId(userId, userType);
            redisClient.set(RedisKeyPrefix.CACHE, key, roleList, 1800);
            return roleList;
        }
    }

    public void deleteUserRoleCache(Long userId) {
        final String key = "ROLES:" + userId.toString();
        redisClient.delete(RedisKeyPrefix.CACHE, key);
    }

    public HashSet<String> queryPremsByRoleId(List<SysRole> roleList, int userType, boolean refreshFlag) {
        HashSet<String> premset = new HashSet<>();
        roleList.forEach(role -> premset.addAll(queryPermissions(role.getId(), userType, refreshFlag)));
        return premset;
    }

    @SuppressWarnings("unchecked")
    private HashSet<String> queryPermissions(Long roleId, int userType, boolean refreshFlag) {
        final String key = "ROLE_PERM:" + roleId.toString();
        if (redisClient.exists(RedisKeyPrefix.CACHE, key) && !refreshFlag) {
            return (HashSet<String>) redisClient.get(RedisKeyPrefix.CACHE, key);
        } else {
            HashSet<String> permissions = new HashSet<>();
            List<String> list = roleDao.queryPermByRoleId(roleId, userType);
            if (list != null && list.size() > 0) {
                permissions = new HashSet<>(list);
                redisClient.set(RedisKeyPrefix.CACHE, key, permissions, 1800);
            }
            return permissions;
        }
    }

    public void deleteRolePremCache(Long roleId) {
        final String key = "ROLE_PERM:" + roleId.toString();
        redisClient.delete(RedisKeyPrefix.CACHE, key);
    }

    @Transactional(rollbackFor = Exception.class)
    public void loginFailProcess(Long userId, Long extendId, Integer userType) {
        /*SysUser sysUser = new SysUser();
        sysUser.setId(userId);
        sysUser.setState(2);
        sysUserDao.updateByPrimaryKeySelective(sysUser);
        if (sysUser.getIsSys() == 1) {
            if (userType == SystemConstants.SYS_TYPE_MERCHANT) {
                Merchant merchant = new Merchant();
                merchant.setId(extendId);
                merchant.setState(2);
                merchantDao.updateByPrimaryKey(merchant);
            } else if (userType == SystemConstants.SYS_TYPE_AGENT) {
                Agent agent = new Agent();
                agent.setId(extendId);
                agent.setState(2);
                agentDao.updateByPrimaryKey(agent);
            }
        }*/
    }
}
